package edu.njucm.herbiv.service.impl;

import edu.njucm.herbiv.dao.AnalysisOrderRepository;
import edu.njucm.herbiv.pojo.entity.AnalysisOrder;
import edu.njucm.herbiv.service.HerbivService;
import edu.njucm.herbiv.utils.FileUtils;
import edu.njucm.herbiv.utils.ScriptUtils;
import jakarta.annotation.Resource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.sql.Timestamp;
import java.util.List;
import java.util.concurrent.CompletableFuture;

/**
 * @Author ZhouHang
 * @Date 24/4/29 029
 */
@Service
public class HerbivServiceImpl implements HerbivService {
    @Resource
    private AnalysisOrderRepository analysisOrderRepository;
    private final Logger logger = LoggerFactory.getLogger(HerbivServiceImpl.class);
    private static final String herbiv = ScriptUtils.pyCommand() + " " + ScriptUtils.runPath;

    @Override
    @Async
    public CompletableFuture<String> fromTcm(List<String> tcms, Timestamp timestamp, String analysisNo) {
        String inputIds = String.join(",", tcms);
        AnalysisOrder analysisOrder = new AnalysisOrder();
        analysisOrder.setInputIds(inputIds);
        analysisOrder.setStatus(0);
        analysisOrder.setCreateTime(timestamp);
        analysisOrder.setUpdateTime(timestamp);
        analysisOrder.setAnalysisNo(analysisNo);
        analysisOrderRepository.save(analysisOrder);

        // 执行 from_tcm 分析
        StringBuilder command = new StringBuilder();
        command.append(herbiv);
        command.append(" --function tcm --tcms ");
        command.append(String.join(" ", tcms));
        String herbivSavePath = ScriptUtils.HERBIV_HOME + File.separator + analysisNo + File.separator;
        command.append(" --path ").append(herbivSavePath);

        logger.info(command.toString());
        String line = "";
        try {
            Process process = Runtime.getRuntime().exec(command.toString());
            BufferedReader in = new BufferedReader(new InputStreamReader(process.getInputStream()));
            line = in.readLine();
            in.close();
        } catch (IOException e) {
            analysisOrder.setStatus(-1);
            analysisOrderRepository.save(analysisOrder);
            logger.warn("IOException");
            return CompletableFuture.completedFuture("IO Error");
        }

        // 将分析结果保存到数据库
        analysisOrder.setResults(line);
        String graphPath = herbivSavePath + File.separator + "Graph.html";
        logger.info(graphPath);
        String graph = FileUtils.readAll(graphPath);
        analysisOrder.setGraph(graph);
        analysisOrder.setStatus(1);
        analysisOrderRepository.save(analysisOrder);
        FileUtils.deleteDirectory(herbivSavePath);
        return CompletableFuture.completedFuture("Success: " + inputIds);
    }

    /**
     * 通过分析号查询分析结果
     * @return 查询失败: null
     * */
    @Override
    public AnalysisOrder getResult(String analysisNo) {
        return analysisOrderRepository.findByAnalysisNo(analysisNo);
    }

    /**
     * 通过分析号查询结果的 echart 图表
     * */
    @Override
    public String getChart(String analysisNo) {
        AnalysisOrder analysisOrder = analysisOrderRepository.findByAnalysisNo(analysisNo);
        if (analysisOrder == null) {
            return "";
        }
        return analysisOrder.getGraph();
    }
}
